package com.zoffy.bi.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yupi.yucongming.dev.model.DevChatResponse;
import com.zoffy.bi.common.BaseResponse;
import com.zoffy.bi.common.ErrorCode;
import com.zoffy.bi.common.ResultUtils;
import com.zoffy.bi.exception.BusinessException;
import com.zoffy.bi.manager.AiManager;
import com.zoffy.bi.manager.RedisLimiterManager;
import com.zoffy.bi.model.dto.chart.GenChartByAiRequest;
import com.zoffy.bi.model.entity.Chart;
import com.zoffy.bi.model.entity.User;
import com.zoffy.bi.model.vo.BiResponse;
import com.zoffy.bi.mq.BiPublisher;
import com.zoffy.bi.service.ChartService;
import com.zoffy.bi.mapper.ChartMapper;
import com.zoffy.bi.service.UserService;
import com.zoffy.bi.utils.ExcelUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
* @author 86170
* @description 针对表【chart(图表信息表)】的数据库操作Service实现
* @createDate 2023-11-14 00:07:47
*/
@Service
public class ChartServiceImpl extends ServiceImpl<ChartMapper, Chart>
    implements ChartService{
    @Resource
    private AiManager aiManager;
    @Resource
    private UserService userService;
    @Resource
    private RedisLimiterManager redisLimiterManager;
    @Resource
    private ThreadPoolExecutor threadPoolExecutor;
    @Resource
    private BiPublisher biPublisher;

    @Override
    public BaseResponse<BiResponse> genChartByAi(MultipartFile multipartFile, GenChartByAiRequest genChartByAiRequest, HttpServletRequest request) {
        //检验
        String name = genChartByAiRequest.getName();
        String goal = genChartByAiRequest.getGoal();
        String chartType = genChartByAiRequest.getChartType();
        //空参数校验
        if(StringUtils.isAnyEmpty(name,goal,chartType)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"请求参数错误");
        }
        //文件大小校验
        long fileSize=multipartFile.getSize();
        final long MB=1024*1024L;
        if (fileSize>MB){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"文件大于1M");
        }

        User loginUser = userService.getLoginUser(request);
        //限流
        String key="genChart_"+loginUser.getId().toString();
        redisLimiterManager.doRateLimit(key);

        StringBuilder userInput =new StringBuilder();
        userInput.append("分析目标:").append("使用").append(chartType).append("类型的图表来").append(goal).append("\n");
        userInput.append("数据:").append("\n");
        String data = ExcelUtils.excel2CSV(multipartFile);
        userInput.append(data);
        String question=userInput.toString();

        //请求Ai
        com.yupi.yucongming.dev.common.BaseResponse<DevChatResponse> baseResponse = aiManager.doChat(question);
        System.out.println(baseResponse.getMessage());
        if (baseResponse.getMessage().equals("消息过长")){
            return ResultUtils.error(ErrorCode.PARAMS_ERROR,"数据量过大");
        }
        String aiResponse=baseResponse.getData().getContent();
        //处理返回结果
        String[] splits = aiResponse.split("￥￥￥");
        String genChart = splits[1].trim();
        String genResult = splits[2].trim();
        //保存数据
        Chart chart=new Chart();
        chart.setGoal(goal);
        chart.setName(name);
        chart.setChartData(data);
        chart.setChartType(chartType);
        chart.setGenChart(genChart);
        chart.setGenResult(genResult);
        chart.setUserId(loginUser.getId());
        chart.setStatus("success");
        this.save(chart);
        //返回响应
        BiResponse response=new BiResponse();
        response.setGenChart(genChart);
        response.setGenResult(genResult);
        return ResultUtils.success(response);
    }
    public BaseResponse<BiResponse> genChartByAiAsync(MultipartFile multipartFile, GenChartByAiRequest genChartByAiRequest, HttpServletRequest request) {
        //检验
        String name = genChartByAiRequest.getName();
        String goal = genChartByAiRequest.getGoal();
        String chartType = genChartByAiRequest.getChartType();
        //空参数校验
        if(StringUtils.isAnyEmpty(name,goal,chartType)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"请求参数错误");
        }
        //文件大小校验
        long fileSize=multipartFile.getSize();
        final long MB=1024*1024L;
        if (fileSize>MB){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"文件大于1M");
        }

        User loginUser = userService.getLoginUser(request);
        //限流
        String key="genChart_"+loginUser.getId().toString();
        redisLimiterManager.doRateLimit(key);

        StringBuilder userInput =new StringBuilder();
        userInput.append("分析目标:").append("使用").append(chartType).append("类型的图表来").append(goal).append("\n");
        userInput.append("数据:").append("\n");
        String data = ExcelUtils.excel2CSV(multipartFile);
        userInput.append(data);
        String question=userInput.toString();
        //保存到数据库
        Chart chart=new Chart();
        chart.setGoal(goal);
        chart.setName(name);
        chart.setChartData(data);
        chart.setChartType(chartType);
        chart.setUserId(loginUser.getId());
        chart.setStatus("wait");
        this.save(chart);
        //异步请求Ai
        CompletableFuture.runAsync(()->{
            //更新生成状态为生成中
            Chart updateChart=new Chart();
            updateChart.setId(chart.getId());
            //调用Ai
            com.yupi.yucongming.dev.common.BaseResponse<DevChatResponse> baseResponse = aiManager.doChat(question);
            System.out.println(baseResponse.getMessage());
            if (baseResponse.getMessage().equals("消息过长")){
                throw new BusinessException(ErrorCode.PARAMS_ERROR,"数据量过大");
            }
            String aiResponse=baseResponse.getData().getContent();
            //处理返回结果chart
            String[] splits = aiResponse.split("￥￥￥");
            String genChart = splits[1].trim();
            String genResult = splits[2].trim();
            //更新生成状态为成果并保存数据
            updateChart.setGenChart(genChart);
            updateChart.setGenResult(genResult);
            updateChart.setStatus("success");
            this.updateById(updateChart);
        },threadPoolExecutor);



        //返回响应
        BiResponse response=new BiResponse();
        return ResultUtils.success(response);
    }

    @Override
    public BaseResponse<BiResponse> genChartByAiMq(MultipartFile multipartFile, GenChartByAiRequest genChartByAiRequest, HttpServletRequest request) {
        //检验
        String name = genChartByAiRequest.getName();
        String goal = genChartByAiRequest.getGoal();
        String chartType = genChartByAiRequest.getChartType();
        //空参数校验
        if(StringUtils.isAnyEmpty(name,goal,chartType)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"请求参数错误");
        }
        //文件大小校验
        long fileSize=multipartFile.getSize();
        final long MB=1024*1024L;
        if (fileSize>MB){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"文件大于1M");
        }

        User loginUser = userService.getLoginUser(request);
        String data = ExcelUtils.excel2CSV(multipartFile);
        //保存到数据库
        Chart chart=new Chart();
        chart.setGoal(goal);
        chart.setName(name);
        chart.setChartData(data);
        chart.setChartType(chartType);
        chart.setUserId(loginUser.getId());
        chart.setStatus("wait");
        this.save(chart);
        //消息队列
        biPublisher.sendMessage(chart.getId());

        //返回响应
        BiResponse response=new BiResponse();
        return ResultUtils.success(response);
    }
}




